"""
2023.5.4
重构matlab中的set_initial_var文件
用python生成对应csv
"""

import csv
import mark
from multiprocessing import Process

csv_name = 'counter.csv'
# mark_out_name = 'SP_out.txt'
# csv_write = open(csv_name, 'w', newline='')
# csv_ = csv.writer(csv_write, dialect='excel')
# csv_write.close()
csv_write = open(csv_name, 'a', newline='')
csv_ = csv.writer(csv_write, dialect='excel')
mark_out_name = 'SP_out.txt'
process = 7  # 多进程，进程个数
# 设定基础进程次数，以2的10次方为准，超过10次方开始增加进程
process_p = 11  # 即2的16次方
num = 0
all_out = []

# 写入csv初始化


def write_csv(ou, csv0):  # 写入csv文件
    global num
    global all_out
    out = []
    for key in ou:
        out.append(ou[key][1])
    all_out.append(out)
    if num < 30:  # 累计一定次数输出一次 降低写入csv频率，防止程序堵塞
        num += 1
    else:
        csv0.writerows(all_out)
        num = 0
        all_out = []


def lock_all_mark(begin, end, out, csv_n, sign):
    global num
    global csv_
    global all_out
    # csv_write0 = open(csv_n, 'w', newline='')
    # csv_o = csv.writer(csv_write0, dialect='excel')
    print(f"the {sign}th process has begun! Goals start at {begin} and end at {end}")
    turn = 0    # 用于测试时标记进程循环次数
    while begin <= end:
        be = begin
        for key in out:
            if out[key][0] == "1":
                pass
            else:
                mark_i = be % 2
                be = be // 2
                out[key][1] = str(mark_i)
        if be != 0:
            begin += 1
            print(f"{begin}存在问题")
            break
        else:
            if (out['12'][1] == '1') or (out['13'][1] == '1') or (out['14'][1] == '1') or (out['15'][1] == '1') or (
                    out['16'][1] == '1') or (out['17'][1] == '1') or (out['18'][1] == '1') or (out['19'][1] == '1') or (
                    out['20'][1] == '1') or (out['21'][1] == '1') or (out['22'][1] == '1') or (out['23'][1] == '1') or (
                    out['24'][1] == '1') or (out['25'][1] == '1') or (out['26'][1] == '1') or (out['27'][1] == '1') or (
                    out['28'][1] == '1') or (out['29'][1] == '1') or (out['30'][1] == '1'):
                write_csv(out, csv_)
        begin += 1
        turn += 1
    if num != 0:
        csv_.writerows(all_out)
        num = 0
        all_out = []
    print(f"the {sign}th process is over! A total of {turn} target states were generated!")


if __name__ == '__main__':
    # csv_name = 'counter.csv'
    # 注意每次运行之前必须修改csv名称，否则不是覆盖，而是增加
    # 该代码用于 以写入形式清空原文件内容
    csv_write = open(csv_name, 'w', newline='')
    csv_ = csv.writer(csv_write, dialect='excel')
    csv_write.close()

    # 导入SP锁定值
    marky, free_i = mark.Mark(mark_out_name)
    all_number = 2 ** free_i - 1
    print(free_i, all_number)
    # 分配进程
    i = 1
    begin0 = 0
    # 设定基础进程次数，以2的process_p次方为准，超过process_p次方开始增加进程
    if all_number < 2**process_p * process:
        long = 2**process_p
    else:
        long = all_number // process + 1
    end0 = begin0 + long - 1
    if end0 > all_number:
        end0 = all_number
    while begin0 <= all_number:
        csv_name0 = csv_name + f'_{i}.csv'
        obj0 = Process(target=lock_all_mark, name=f'the {i}th process', args=(begin0, end0, marky, csv_name0, i))
        obj0.start()
        begin0 = end0 + 1
        end0 = end0 + long
        if end0 > all_number:
            end0 = all_number
        i += 1
    print("end of main program")
